package com.spring.mvc.loader;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

public class JarResources {

	private boolean debugOn=false;
	private Hashtable<String, Integer> htSize=new Hashtable<String, Integer>();
	private Hashtable<String, byte[]> htJarContents=new Hashtable<String, byte[]>();
	
	private String jarFileName;
	private long lastModify;
	
	public JarResources(String jarFileName) {
		this.jarFileName=jarFileName;
		init();
	}
	
	public byte[] getResource(String name){
		return this.htJarContents.get(name);
	}
	
	private void init(){
		FileInputStream fis=null;
		try {
			File file=new File(jarFileName);
			this.lastModify=file.lastModified();
			
			ZipFile zf=new ZipFile(this.jarFileName);
			Enumeration<?> e=zf.entries();
			while(e.hasMoreElements()){
				ZipEntry ze=(ZipEntry)e.nextElement();
				if(this.debugOn){
					System.out.println(dumpZipEntry(ze));
				}
				if(!ze.isDirectory())
					this.htSize.put(ze.getName(), (int)ze.getSize());
			}
			zf.close();
			
			fis=new FileInputStream(this.jarFileName);
			BufferedInputStream bis=new BufferedInputStream(fis);
			ZipInputStream zis=new ZipInputStream(bis);
			ZipEntry ze=null;
			while((ze=zis.getNextEntry())!=null){
				if(ze.isDirectory()){
					continue;
				}
				if(this.debugOn){
					System.out.println("日志");
				}
				int size=(int)ze.getSize();
				if(size==-1){
					size=this.htSize.get(ze.getName()).intValue();
				}
				byte[] b=new byte[size];
				int rb=0;
				int chunk=0;
				while(size-rb>0){
					chunk=zis.read(b,rb,size-rb);
					if(chunk==-1){
						break;
					}
					rb+=chunk;
				}
				this.htJarContents.put(ze.getName(), b);
				if(this.debugOn){
					System.out.println("日志");
				}
			}
			Iterator<String> jarKeys=htJarContents.keySet().iterator();
			while(jarKeys.hasNext()){
				System.out.println(jarKeys.next());
			}
		} catch (ZipException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			try {
				if(fis != null){
					fis.close();
					fis=null;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	private String dumpZipEntry(ZipEntry ze){
		StringBuilder sb=new StringBuilder();
		if(ze.isDirectory()){
			sb.append("d "); 
		}else{
			sb.append("f ");
		}
		if(ze.getMethod()==0){
			sb.append("stored ");
		}else{
			sb.append("defalted ");
		}
		
		sb.append(ze.getName());
		sb.append("\t");
		sb.append(ze.getSize());
		if(ze.getMethod()==8){
			sb.append("/"+ze.getCompressedSize());
		}
		return sb.toString();
	}
	
	public void destory(){
		this.htJarContents.clear();
		this.htSize.clear();
	}
	
	public boolean isChanged(){
		File file=new File(this.jarFileName);
		if(this.lastModify!=file.lastModified()){
			this.lastModify=file.lastModified();
			return true;
		}
		return false;
	}
	
	public Enumeration<String> getAllResourceNames(){
		return this.htJarContents.keys();
	}
}
